#include "scripting/scripting_api.h"
#include "utils/log.hpp"

#include "scripting/scripting_module.h"

IScript::IScript (ScriptUsage usage, std::string title, std::string file, const ScriptModuleInfo *smi) : usage_ (usage), title_ (std::move (title)), file_(std::move(file)), smi_ (smi) {}

IScript::~IScript () = default;

const char *IScript::title() const
{
    return title_.c_str();
}

const char *IScript::lang() const
{
    return smi_->lang;
}

const char *IScript::file() const
{
    return file_.c_str();
}

ScriptUsage IScript::usage() const
{
    return usage_;
}

bool IScript::reload()
{
    if (reloadable())
        return real_reload();
    return false;
}

bool IScript::reloadable() const
{
    return smi_->support_hot_reload;
}

bool IScript::real_reload()
{
    L_WARN("UNIMPLEMENT: %s script RELOAD logic!", smi_->name);
    return false;
}

IFunctionalScript::IFunctionalScript (std::string title, std::string file, const ScriptModuleInfo *smi) : IScript (ScriptUsage::eFunction, std::move (title), std::move(file), smi) {}

IEditorScript::IEditorScript (IEditorScript::EditorTarget target, std::string title, std::string file, const ScriptModuleInfo *smi) :
    IScript (ScriptUsage::eEditor, std::move (title), std::move(file), smi), apply_target_ (target)
{
}

IEditorScript::EditorTarget IEditorScript::target() const
{
    return apply_target_;
}

static const char *editor_target_names[] = {
        "item",
        "daily",
        "month",
        "year",
};

IEditorScript::EditorTarget EditorTargetFromString (const char *target)
{
    for (auto i = 0; i < (int) IEditorScript::eCount; ++i)
    {
        if (strcmp (target, editor_target_names[i]) == 0)
            return static_cast<IEditorScript::EditorTarget> (i);
    }
    L_ERROR ("Unknown editor target %s", target);
    return IEditorScript::eCount;
}

const char *EditorTargetToString (IEditorScript::EditorTarget target)
{
    if (target >= IEditorScript::eItem && target < IEditorScript::eCount)
        return editor_target_names[(int) target];
    L_ERROR ("Editor target out-of-range: %d", (int) target);
    return "UNKNOWN";
}
bool IFunctionalScript::call (const void *)
{
    execute ();
    return true;
}
bool IEditorScript::call (const void *arg)
{
    execute (arg);
    return true;
}
